之前有介紹過7-segment的運作原理,今天要在arduino使用7-segment這個元件~
在模擬器中,arduino有提供1-digit的7-segment以及4-digit的7-segment。
他們共同的引腳有A、B、C、D、E、F、G、DP;這幾個引腳是負責決定「段」的顯示,而DP是用來控制小數點的部分。
那在4-digit的部分,因為還要控制要由哪一個7-segment來顯示數字,所以他比1-digit的多了四個引腳-DIG1、DIG2、DIG3、DIG4,要控制由誰發亮,就寫入指定的引腳,狀態設為HIGH,等等舉例會使用到。
先來介紹1-digit的元件~
那從模擬器的圖能看到,上下邊皆有五個引腳,這些引腳代表了A~DP,還有兩個是COM1及COM2。
A~DP的部分,接上數位腳位,這邊就先接在D2~D9。
COM1及COM2是公共引腳,這邊可以不用接。
接好後的樣子:
再來看程式碼。
因為要連接的引腳有「7段+DP」,所以我開一個segment陣列,負責存這7個段接到的腳位,以及DP連接的腳位,這邊就根據接線的狀況寫啦~
那接著是數字0~9的部分,再開一個number[10][8]的二維陣列,10代表有10個數字(0~9)、8代表「7段+DP」,其中儲存的值只有0跟1,row的索引值即為代表的數字,根據數字來決定他的「七段+DP」的狀態,1為亮、0為不亮。
那因為這邊其實不會用到DP,所以可以省略DP的部分,就陣列都少開一個空間。
那變數的部分就宣告完成!接著是setup,這邊的話八個使用到的腳位要設為OUTPUT。
然後是loop,一開始我先寫一個function,用來初始化LED燈,讓他都不亮。
然後要把7-segment打開。
接著是主要的displayNumber啦~這邊設定是從0亮到9、再從0開始繼續亮。
displayNumber在一個for迴圈內,這個for迴圈會由0跑到9,所以displayNumber要顯示的數字就是根據for迴圈當前的索引值。
首先我先測當前數字的8個值,如果是1就亮該LED段、0就跳過,且亮1秒。
這邊要注意的是,在這個7-segment的LED片段中,LOW表示亮、HIGH表示關,然後把要亮的片段都打開後,再執行delay。
亮好1秒後,我再呼叫一次initial,把所有LED片段關掉,維持關掉的狀態0.5秒。
然後再繼續亮下一個數字。
int segment[8] = {2,3,4,5,6,7,8,9};
int number[10][8] =
{
{1,1,1,1,1,1,0,0}, //0
{0,1,1,0,0,0,0,0}, //1
{1,1,0,1,1,0,1,0}, //2
{1,1,1,1,0,0,1,0}, //3
{0,1,1,0,0,1,1,0}, //4
{1,0,1,1,0,1,1,0}, //5
{1,0,1,1,1,1,1,0}, //6
{1,1,1,0,0,0,0,0}, //7
{1,1,1,1,1,1,1,0}, //8
{1,1,1,1,0,1,1,0} //9
};
void setup() { //將8個腳位設為OUTPUT
for( int i = 0; i < 8; ++i ){
pinMode( segment[i], OUTPUT );
}
}
void loop()
{
initial(); //初始化
digitalWrite(10,HIGH); //打開7-segment
for( int i = 0; i < 10; ++i ){ //從0跑到9
displayNumber( i ); //在7-segment顯示當前for迴圈的索引值
delay(1000); //顯示1秒
initial(); //關掉
delay(500); //延遲0.5秒
}
}
void initial()
{
for( int i = 0; i < 8; ++i ){
digitalWrite( segment[i],HIGH ); //把每個片段都關掉
}
}
void displayNumber( int i )
{
for( int j = 0; j < 8; ++j ){
if( number[i][j] == 1 ){ //表示要亮
digitalWrite( segment[j], LOW ); //打開該LED片段
}
}
}
大概就是這樣~
接著來看4-digit的部分。
A~DP引腳的部分,跟1-digit一樣,連接到arduino板上的腳位(使用D2~D9)。
再來是1-digit沒有的的DIG1~DIG4的部分,這邊就使用D10~D13。
喔對,然後4-digit沒有COM1跟COM2。
放上接好的圖~
接好後,就根據接線的狀態來寫code啦~
這邊因為多了DIG1~DIG4,所以多設了一個陣列display[4],用來儲存這四個DIG分別接在哪一個角位。
然後因為我想要四個7-segment輪流顯示數值、一次只有一個顯示,所以我新增了一個變數k,用來表示現在要在哪一個7-segment顯示數值;k初值為0,每亮一次就+1,然後再mod 4取餘數,這是其中一個輪流0~3的方法。
其餘部分就跟1-digit的差不多~
以下的程式碼,執行後會是從0開始顯示到9,再回到0,然後四個7-segment會輪流顯示。
int display[4] = {10,11,12,13};
int segment[8] = {2,3,4,5,6,7,8,9};
int number[10][8] =
{
{1,1,1,1,1,1,0,0}, //0
{0,1,1,0,0,0,0,0}, //1
{1,1,0,1,1,0,1,0}, //2
{1,1,1,1,0,0,1,0}, //3
{0,1,1,0,0,1,1,0}, //4
{1,0,1,1,0,1,1,0}, //5
{1,0,1,1,1,1,1,0}, //6
{1,1,1,0,0,0,0,0}, //7
{1,1,1,1,1,1,1,0}, //8
{1,1,1,1,0,1,1,0} //9
};
int k = 0;
void setup() {
for( int i = 0; i < 8; ++i ){
pinMode( segment[i], OUTPUT );
}
}
void loop()
{
initial();
for( int i = 0; i < 10; ++i ){
digitalWrite( display[k%4], HIGH );
displayNumber( i );
delay(1000);
initial();
delay(500);
k++;
}
}
void initial()
{
digitalWrite( display[k%4], LOW ); //把當前使用的7-segment關掉
for( int i = 0; i < 8; ++i ){
digitalWrite( segment[i],HIGH );
}
}
void displayNumber( int i )
{
for( int j = 0; j < 8; ++j ){
if( number[i][j] == 1 ){
digitalWrite( segment[j], LOW );
}
}
}
那今天就先這樣~